﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using MySql.Data.MySqlClient;
using Services.Common;
using BartonExtension;
using SQLWrapper;
using Model.App;
using Model.Images;
using Model.Weixin;
using Model;

namespace Services.Form
{
    public class ISMFormServiceProvider : ISMServiceProvider
    {
        public const string GET_FORM_FIELDS = "get_form_fields";
        public const string FILL_FORM = "fill_form";
        public const string SET_FORM_TEMPLATE = "set_form_template";
        public override Task<ISMServiceResult> doProcess(ISMServiceModel model)
        {
            if(model.operationIdentifier == GET_FORM_FIELDS)
            {
                string token = model.GetState<string>();
                return GetFormFields(token);
            }
            else if(model.operationIdentifier == SET_FORM_TEMPLATE)
            {
                ISMNewFormTemplateRequest request = model.GetState<ISMNewFormTemplateRequest>();
                return NewFormTemplate(request);
            }
            else if(model.operationIdentifier == FILL_FORM)
            {
                ISMFormFilledRequest request = model.GetState<ISMFormFilledRequest>();
                return FillForm(request);
            }
            else
            {
                return base.defaultProcess();
            }
        }
        private Task<ISMServiceResult> NewFormTemplate(ISMNewFormTemplateRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(()=>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    string identifier = IDGenerator.GenerateID().ToString();
                    MySQLOperationManager.doSQLOperation(cmd=>
                        {
                            cmd.CommandText = "proc_client_new_form";
                            cmd.Parameters.Add("?_field_ids",request.field_ids,ParameterDirection.Input);
                            cmd.Parameters.Add("?_identifier",identifier,ParameterDirection.Input);
                            cmd.Parameters.Add("?_token",request.token,ParameterDirection.Input);
                            cmd.Parameters.Add("?errorcode",MySqlDbType.Int32,ParameterDirection.Output);
                            cmd.ExecuteNonQuery();
                            int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                            if(errorcode == 0)
                            {
                                result.dbReturningState = identifier;
                            }
                            else if(errorcode == -1)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                                result.errorMsg = "Token 验证失败";
                            }
                            else if(errorcode == -2)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_FORM_DUMPLICATED_FORM;
                                result.errorMsg = "Form ID冲突";
                            }
                        },
                        e=>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = e;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            }
                        },CommandType.StoredProcedure,false);
                    return result;
                });
        }
        private Task<ISMServiceResult> FillForm(ISMFormFilledRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    
                    MySQLOperationManager.doSQLOperation(cmd =>
                        {
                            cmd.CommandText = "proc_client_add_filled_form";
                            cmd.Parameters.Add("?_form_data", request.filledForm.Serialize(), ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                            cmd.Parameters.Add("?errorcode", MySqlDbType.Int32, ParameterDirection.Output);
                            cmd.Parameters.Add("?formid", MySqlDbType.Int32, ParameterDirection.Output);
                            cmd.ExecuteNonQuery();
                            int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                            if(errorcode == 0)
                            {
                                result.dbReturningState = cmd.Parameters["?formid"].Value.toInt32().Value;
                            }
                            else if(errorcode == -1)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "Token 验证失败";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            }
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = e;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }

        private Task<ISMServiceResult> GetFormFields(string token)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                        {
                            cmd.CommandText = "proc_client_get_form_fields";
                            cmd.Parameters.Add("?_token", token, ParameterDirection.Input);
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = e;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            }
                        },
                        data =>
                        {
                            if(data.Count == 1 && data.First().ContainsKey("error"))
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                                result.errorMsg = "Token 验证失败";
                            }
                            else
                            {
                                ISMForm form = ISMForm.NewForm();
                                data.ForEach(d =>
                                    {
                                        ISMFormField field = new ISMFormField()
                                        {
                                            field_name = d["field_name"].ToString(),
                                            field_type = d["field_type"].toEnum<ISMFormFieldType>(),
                                            field_desc = d["field_desc"].ToString(),
                                            ID = d["ID"].toUInt64().Value
                                        };
                                        form.fields.Add(field);
                                    });
                                result.dbReturningState = form;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
    }
}
